package com.dc.business.datacollectbusiness.utils;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.security.Security;
import java.util.Base64;

// AES算法工具类
public class AESUtil {

    // 密钥,Text格式
    static String key = "3AE8664CDC4E2A1A";
    // 偏移量,Text格式
    static String iv = "0000000000000000";

    static {
        // 注册Bouncy Castle提供者
        Security.addProvider(new BouncyCastleProvider());
    }

    // 编码函数
    public static String encrypt(String requestJSON) throws Exception {
        // 将密钥和 IV 转换为字节数组
        SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes("UTF-8"));

        // 创建 Cipher 实例并初始化为加密模式
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);

        // 执行加密操作
        byte[] encryptedBytes = cipher.doFinal(requestJSON.getBytes("UTF-8"));

        // 将加密后的字节数组转换为 BASE64 编码的字符串
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }


    // 解码函数
    public static String decrypt(String encryptedText) throws Exception {
        // 解码Base64编码的输入文本
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText);

        // 设置加密参数
        byte[] keyBytes = textToFixedByteArray(key, 16, "UTF-8");  // 秘钥必须是16字节
        byte[] ivBytes = textToFixedByteArray(iv, 16, "UTF-8");    // IV也必须是16字节

        // 创建秘钥和IV对象
        SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES");
        IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);

        // 初始化Cipher对象，指定使用AES算法、CBC模式以及NoPadding填充方式
        Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "BC");
        cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);

        // 解密数据
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);

        // 处理ZeroPadding: 去除末尾多余的0字节
        int i = decryptedBytes.length - 1;
        while (i >= 0 && decryptedBytes[i] == 0) {
            i--;
        }
        byte[] trimmedDecryptedBytes = new byte[i + 1];
        System.arraycopy(decryptedBytes, 0, trimmedDecryptedBytes, 0, i + 1);

        // 返回解密后的字符串，使用UTF-8字符集解码
        return new String(trimmedDecryptedBytes, "UTF-8");
    }


    // 加工到规定长度
    private static byte[] textToFixedByteArray(String text, int length, String encoding) throws Exception {
        byte[] bytes = text.getBytes(encoding);
        if (bytes.length >= length) {
            return java.util.Arrays.copyOf(bytes, length);  // 截断到指定长度
        } else {
            byte[] paddedBytes = new byte[length];
            System.arraycopy(bytes, 0, paddedBytes, 0, bytes.length);
            return paddedBytes;  // 填充到指定长度
        }
    }
}
